﻿using FlexFlow.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FlexFlow.Base.Application
{
    /// <summary>
    /// 表示工作流任务工厂
    /// </summary>
    public class WorkFlowTaskFactory
    {
        /// <summary>
        /// 获取该工厂绑定的任务接收者列表
        /// </summary>
        public HashSet<Guid> Recivers { get; private set; }
        /// <summary>
        /// 获取该工厂绑定的任务提交处理函数
        /// </summary>
        public AbstractApplication.TaskSubmitProcessAction Processor { get; private set; }
        /// <summary>
        /// 获取该工作流任务工厂绑定的应用程序
        /// </summary>
        public AbstractApplication Application { get; private set; }
        /// <summary>
        /// 获取该工厂构造的任务类型
        /// </summary>
        public string TaskType { get; private set; }
        /// <summary>
        /// 获取该工厂的任务发送数据
        /// </summary>
        public Dictionary<string, object> SendDatas { get; private set; }
        /// <summary>
        /// 为当前任务绑定处理函数
        /// </summary>
        /// <param name="processor">
        /// 要绑定的处理函数
        /// </param>
        public WorkFlowTaskFactory BindProcessor(AbstractApplication.TaskSubmitProcessAction processor)
        {
            if (processor.Target != this.Application)
            {
                throw new ArgumentException("处理方法必须为当前应用程序内的方法！");
            }
            this.Processor = processor;
            return this;
        }
        /// <summary>
        /// 添加任务的接收者
        /// </summary>
        /// <param name="recivers">
        /// 任务接收者
        /// </param>
        public WorkFlowTaskFactory AddRecivers(params Guid[] recivers)
        {
            foreach (var reciver in recivers)
            {
                this.Recivers.Add(reciver);
            }
            return this;
        }
        /// <summary>
        /// 设置任务类型
        /// </summary>
        /// <param name="taskType">
        /// 要设置的任务类型文本
        /// </param>
        /// <returns></returns>
        public WorkFlowTaskFactory SetTaskType(string taskType)
        {
            this.TaskType = taskType;
            return this;
        }
        /// <summary>
        /// 添加发送数据
        /// </summary>
        /// <param name="datas">
        /// 数据集合
        /// </param>
        /// <returns></returns>
        public WorkFlowTaskFactory AddSendDatas(params KeyValuePair<string, object>[] datas)
        {
            foreach (var data in datas)
            {
                this.SendDatas[data.Key] = data.Value;
            }
            return this;
        }
        /// <summary>
        /// 添加发送数据
        /// </summary>
        /// <param name="key">
        /// 键
        /// </param>
        /// <param name="val">
        /// 值
        /// </param>
        /// <returns></returns>
        public WorkFlowTaskFactory AddSendData(string key, object val)
        {
            this.SendDatas[key] = val;
            return this;
        }
        private void InitTaskReciver(WorkFlowTask task)
        {
            StringBuilder sb = new StringBuilder((Guid.Empty.ToString().Length + 1) * this.Recivers.Count);
            foreach (var reciver in this.Recivers)
            {
                sb.Append(reciver.ToString());
                sb.Append(",");
            }
            task.Reciver = sb.ToString();
        }
        /// <summary>
        /// 创建审批任务
        /// </summary>
        /// <returns>
        /// 创建的审批任务实例
        /// </returns>
        public WorkFlowTask CreateApprovalTask()
        {
            return CreateTask(SystemTaskType.ApprovalTask);
        }
        /// <summary>
        /// 创建任务
        /// </summary>
        /// <param name="type">
        /// 任务类型
        /// </param>
        /// <returns>
        /// 创建的任务实例
        /// </returns>
        public WorkFlowTask CreateTask(string type = "")
        {
            if (this.TaskType == string.Empty && type == "")
            {
                throw new InvalidOperationException("未指定任务的类型，构建任务失败！");
            }
            WorkFlowTask task = new WorkFlowTask();
            this.InitTaskReciver(task);
            task.SendData["TaskSubmitProcessor"] = this.Processor.Method.Name;
            foreach (var data in SendDatas)
            {
                task.SendData.Add(data.Key, data.Value);
            }
            task.Type = type == "" ? this.TaskType : type;
            return task;
        }



        public WorkFlowTaskFactory(AbstractApplication app)
        {
            this.Application = app;
            this.TaskType = string.Empty;
            this.SendDatas = new Dictionary<string, object>();
            this.Recivers = new HashSet<Guid>();
            this.Processor = null;
        }
    }
}
